package com.hyzh.latte.vehicle.controller;

import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.util.StrUtil;
import com.coffee.core.CoffeeResponse;
import com.coffee.core.CoffeeResponseEnum;
import com.hyzh.latte.util.LatteResponseCode;
import com.hyzh.latte.util.gather.OkhttpUtil;
import com.hyzh.latte.vehicle.dmo.*;
import com.hyzh.latte.vehicle.dmo.entity.ParkPGEntity;
import com.hyzh.latte.vehicle.dmo.entity.VehicleTrackRecordPGEntity;
import com.hyzh.latte.vehicle.nezha.NezhaPersonManager;
import com.hyzh.latte.vehicle.service.NezhaRecordService;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;

import java.time.LocalDateTime;
import java.time.ZoneOffset;
import java.time.format.DateTimeFormatter;
import java.time.temporal.ChronoUnit;
import java.util.ArrayList;
import java.util.List;
import java.util.Set;
import java.util.stream.Collectors;

/**
 * @author songkui
 * @since 2024/4/12 19:08
 */
@CrossOrigin
@RestController
@RequestMapping("/cors/history")
@Slf4j
@AllArgsConstructor
//@CrossOrigin
public class HistoryCorsTrackController {


    private final NezhaRecordService nezhaRecordService;


    // 车辆流数据 -- 流媒体
    @GetMapping("/historyStream")
    public CoffeeResponse<List<StreamDataResponse>> historyStream(@RequestHeader("park") String park,
                                                                  @RequestParam("vno") String vno,
                                                                  @RequestParam(name = "start", required = false) String startTime,
                                                                  @RequestParam(name = "end", required = false) String endTime) {

        if (StrUtil.isEmpty(startTime) || StrUtil.isEmpty(endTime)) {
            return CoffeeResponse.response(CoffeeResponseEnum.ParamInvalid);
        }
        ParkPGEntity parkEntity = NezhaPersonManager.getInstance().parkPGEntity(park);
        if (null == parkEntity){
            log.error("historyStream handler>> park  null; park: {}", park);
            return CoffeeResponse.response(LatteResponseCode.ParamInvalid);
        }

        DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
        LocalDateTime startDateTime = LocalDateTime.parse(startTime, formatter);
        LocalDateTime endDateTime = LocalDateTime.parse(endTime, formatter);
        long days = startDateTime.until(endDateTime, ChronoUnit.DAYS);
        if (days > 7) {
            return CoffeeResponse.responseMessage(CoffeeResponseEnum.ParamInvalid.code(), "时间间隔不能大于7天");
        }

        List<VehicleTrackRecordPGEntity> list = nezhaRecordService.listTrackRecord(park, vno, startDateTime, endDateTime);
        if (CollectionUtil.isEmpty(list)) {
            log.info("historyStream: history data is null, vno: {}", vno);
            return CoffeeResponse.response(LatteResponseCode.ExcelNotData);
        }
        Set<String> cs = list.stream().map(VehicleTrackRecordPGEntity::getCameraCode).collect(Collectors.toSet());
        List<StreamDataRequest> sl = new ArrayList<>(cs.size());
        long st = startDateTime.toEpochSecond(ZoneOffset.of("+8"));
        long et = endDateTime.toEpochSecond(ZoneOffset.of("+8"));
        int i = 1;
        for (String c : cs) {
            sl.add(new StreamDataRequest(i, c, st, et));
            ++i;
        }

        StreamResponse response = OkhttpUtil.doPostStream(new StreamRequest(sl), parkEntity.getStreamUrl());
        if (null == response || CollectionUtil.isEmpty(response.getData())){
            log.info("historyStream: post data is null: park: {} vno: {}", park, vno);
            return CoffeeResponse.response(LatteResponseCode.ExcelNotData);
        }

        return CoffeeResponse.responseSuccess(response.getData());
    }

    //摄像头流
    @GetMapping("/history-stream")
    public CoffeeResponse<List<StreamDataResponse>> historyStreamByCamera(@RequestHeader("park") String park,
                                                                          @RequestParam("cno") String cno,
                                                                  @RequestParam(name = "start") String startTime,
                                                                  @RequestParam(name = "end") String endTime) {



        ParkPGEntity parkEntity = NezhaPersonManager.getInstance().parkPGEntity(park);
        if (null == parkEntity || StrUtil.isEmpty(parkEntity.getStreamUrl())){
            log.error("historyStream handler>> park  null; park: {}", park);
            return CoffeeResponse.response(LatteResponseCode.ParamInvalid);
        }

        DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
        LocalDateTime startDateTime = LocalDateTime.parse(startTime, formatter);
        LocalDateTime endDateTime = LocalDateTime.parse(endTime, formatter);
        long days = startDateTime.until(endDateTime, ChronoUnit.HOURS);
        if (days > 3) {
            List<StreamDataResponse> list = new ArrayList<>();
            LocalDateTime tempEnd;
            boolean isDo = true;
            while (isDo){
                tempEnd = startDateTime.plusHours(2);
                if (endDateTime.isBefore(tempEnd)){
                    isDo = false;
                    tempEnd = endDateTime;
                }
                if (!startDateTime.isEqual(tempEnd)){
                    List<StreamDataResponse> sl = OkhttpUtil.pullStreamByTime(startDateTime, tempEnd, cno, parkEntity, park);
                    if (CollectionUtil.isNotEmpty(sl)){
                        list.addAll(sl);
                    }
                }
                startDateTime = tempEnd;

            }

            if (CollectionUtil.isEmpty(list)){
                return CoffeeResponse.response(LatteResponseCode.ExcelNotData);
            }

            return CoffeeResponse.responseSuccess(list);
        }

        List<StreamDataResponse> list = OkhttpUtil.pullStreamByTime(startDateTime, endDateTime, cno, parkEntity, park);
        if (CollectionUtil.isEmpty(list)){
            return CoffeeResponse.response(LatteResponseCode.ExcelNotData);
        }

        return CoffeeResponse.responseSuccess(list);

    }


    @GetMapping("/screenshot-stream")
    public ResponseEntity<byte[]> screenshotStream(@RequestHeader("park") String park,
                                                     @RequestParam(name = "cno", required = false) String cno,
                                                     @RequestParam(name = "surl", required = false) String surl) {
        ParkPGEntity parkEntity = NezhaPersonManager.getInstance().parkPGEntity(park);
        if (null == parkEntity || StrUtil.isEmpty(parkEntity.getStreamUrl())){
            log.error("historyStream handler>> park  null; park: {}", park);
            return ResponseEntity.status(HttpStatus.PRECONDITION_REQUIRED).build();
        }
        if (StrUtil.isEmpty(cno) && StrUtil.isEmpty(surl)){
            log.error("historyStream handler>> param is  null");
            return ResponseEntity.status(HttpStatus.PRECONDITION_REQUIRED).build();
        }

        byte[] bytes = OkhttpUtil.findScreenshot(new ScreenshotRequest(cno, surl), park, parkEntity.getStreamUrl());
        if (null != bytes){
            HttpHeaders headers = new HttpHeaders();
            headers.setContentType(MediaType.IMAGE_JPEG);
            headers.setContentLength(bytes.length);
            return ResponseEntity.ok()
                    .headers(headers)
                    .body(bytes);
        }
        return ResponseEntity.status(HttpStatus.PRECONDITION_REQUIRED).build();
    }

 /*   //历史视频流
    private List<StreamDataResponse> pullStream(String cno, long st, long et, String url, String park){

        final String api = "/v2/smc/web/getmergeurl_v2";

        List<StreamDataRequest> sl = new ArrayList<>(1);
        sl.add(new StreamDataRequest(1, cno, st, et));
        StreamResponse response = OkhttpUtil.doPostStream(new StreamRequest(sl), url+api);
        if (null == response || CollectionUtil.isEmpty(response.getData())){
            log.info("historyStream: post data is null: park: {} vno: {}", park, cno);
            return null;
        }
        List<StreamDataResponse> list =  response.getData();
        if (CollectionUtil.isNotEmpty(list)){
            for (StreamDataResponse d : list){
                d.setCno(cno);
            }
        }

        return list;
    }*/


}
